#include<iostream>
#include<WinSock2.h>
#include <thread>
#include<string>
#include <time.h>
#pragma warning(disable:4996)
#pragma comment (lib, "ws2_32.lib")  //加载 ws2_32.dll
using namespace std;

const int MAXBUF = 1024;
const double TIMEOUT = 0.5 * CLOCKS_PER_SEC;
#define SYN 4
#define ACK 2
#define FIN 1
#define ACK_SYN 6
#define ACK_FIN 3

struct HEADER {
	u_short len = 0;//2
	u_short ck_sum = 0;//2
	u_short flag = 0;//[SYN ACK FIN]	//2
	unsigned char seq_num = 0;//1
	unsigned char ack_num = 0;//1
}head;
u_short cksum(u_short* mes, int count) {//u_short宏定义为short类型，占2个字节；以16位为单位取报文(mes) 
	//mes指向报文，count表示报文-16位 为单位的组数
	u_long sum = 0;
	while (count--) {
		sum += *mes++;//以16位为单位累加
		if (sum & 0xffff0000) {//如果超出了两个字节，说明有溢出
			sum &= 0xffff;//只保留低两个字节
			sum++;
		}
	}
	return ~(sum & 0xffff);
}
char szBuffer[MAXBUF] = { 0 };
void shake(SOCKET sock, SOCKADDR* sockAddr) {//三次握手
	//socket, 缓冲区，大小，NULL
	//第一次握手
	int len = sizeof(sockAddr);
	head.len = 8;//8个字节
	head.flag = SYN;
	srand((unsigned)time(NULL));
	head.seq_num = rand() % (MAXBYTE);//产生随机序列号
	cout << "第一次握手产生的Seq序列号为：" << (int)head.seq_num << endl;
	head.ack_num = 0;
	head.ck_sum = 0;
	head.ck_sum = cksum((u_short*)&head, head.len / 2 + head.len % 2);

	char* buf = new char[head.len];
	memcpy(buf, &head, head.len);
	clock_t start;

	if (sendto(sock, buf, head.len, 0, (struct sockaddr*)&sockAddr, sizeof(sockAddr)) == SOCKET_ERROR) {
		cout << "send发送失败！重新发送..." << endl;
	}
	cout << "等待第二次握手中....." << endl;
	start = clock();
	//接收第二次握手


	while (1) {
		if (clock() - start > TIMEOUT) {
			cout << "超时...重传中..." << endl;
			while (sendto(sock, buf, head.len, 0, (struct sockaddr*)&sockAddr, sizeof(sockAddr)) == SOCKET_ERROR) {
				cout << "send发送失败！重新发送..." << endl;
			}
			cout << "等待第二次握手中....." << endl;
			start = clock();
		}
		else {
			//recv(sock, buf, 8, 0);
			recvfrom(sock, buf, 8, 0, (sockaddr*)&sockAddr, (&len));
			HEADER* recv_head = (HEADER*)buf;
			if (cksum((u_short*)buf, 4) != 0xffff) {
				cout << "error!传输错误" << endl;//等待重传
			}
			else {
				if (recv_head->flag == ACK_SYN) {
					cout << "成功接收第二次握手内容!" << endl;
					cout << "第二次握手中Ack为" << (int)recv_head->ack_num << endl;
					cout << "第二次握手中Seq为" << (int)recv_head->seq_num << endl;
					break;
				}
			}
		}
	}
	//发送第三次握手内容
	head.len = 8;//8个字节
	head.flag = SYN;
	srand((unsigned)time(NULL));
	head.seq_num = rand() % (MAXBYTE);//产生随机序列号
	head.ack_num = 0;
	head.ck_sum = 0;
	head.ck_sum = cksum((u_short*)&head, head.len / 2 + head.len % 2);

	memcpy(buf, &head, head.len);
	while (sendto(sock, buf, head.len, 0, (struct sockaddr*)&sockAddr, sizeof(sockAddr)) == SOCKET_ERROR) {
		cout << "send发送失败！重新发送..." << endl;
	}
	cout << "第三次握手已发送.....可以进行数据传输..." << endl;
	// 	   0008 FFE6 0004 0D 00
	//while(send(sock))

}
int main() {
	cout << "客户端" << endl;
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);//希望用户使用2.2版本的Socket
	SOCKET sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);


	struct sockaddr_in sockAddr;//sockaddr_in用作定义，socketaddr用作函数参数
	memset(&sockAddr, 0, sizeof(sockAddr));  //将结构体清零
	sockAddr.sin_family = PF_INET;//TCP
	sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");//指定服务器IP
	sockAddr.sin_port = htons(1234);//指定服务器端口
	//shake(sock, (SOCKADDR*)&sockAddr);


	int len = sizeof(sockAddr);
	head.len = 8;//8个字节
	head.flag = SYN;
	srand((unsigned)time(NULL));
	head.seq_num = rand() % (MAXBYTE);//产生随机序列号
	cout << "第一次握手的Seq序列号为：" << (int)head.seq_num << endl;
	cout << "第一次握手的Ack序列号为：" << (int)head.ack_num << endl;
	head.ack_num = 0;
	head.ck_sum = 0;
	head.ck_sum = cksum((u_short*)&head, head.len / 2 + head.len % 2);

	char* buf = new char[head.len];
	memcpy(buf, &head, head.len);
	clock_t start;
again:
	if (sendto(sock, buf, head.len, 0, (struct sockaddr*)&sockAddr, sizeof(sockAddr)) == SOCKET_ERROR) {
		cout << "send发送失败！重新发送..." << endl;
		goto again;
	}

	cout << endl << "等待第二次握手中....." << endl;
	start = clock();
	//接收第二次握手
	HEADER* recv_head;
	while (1) {
		if (clock() - start > TIMEOUT) {
			cout << "超时...重传中..." << endl;
			while (sendto(sock, buf, head.len, 0, (struct sockaddr*)&sockAddr, sizeof(sockAddr)) == SOCKET_ERROR) {
				cout << "send发送失败！重新发送..." << endl;
			}
			cout << endl << "等待第二次握手中....." << endl;
			start = clock();
		}
		else {
			//recv(sock, buf, 8, 0);
			recvfrom(sock, buf, 8, 0, (sockaddr*)&sockAddr, (&len));
			recv_head = (HEADER*)buf;
			if (cksum((u_short*)buf, 4) != 0x0000) {
				cout << "error!第二次握手传输中出现错误！" << endl;//等待重传
			}
			else {
				if (recv_head->flag == ACK_SYN) {
					cout << "成功接收第二次握手内容!" << endl;
					cout << "第二次握手中Ack为" << (int)recv_head->ack_num << endl;
					cout << "第二次握手中Seq为" << (int)recv_head->seq_num << endl;
					break;
				}
			}
		}
	}
	//发送第三次握手内容
	cout << endl << "进行第三次握手:" << endl;
	head.len = 8;//8个字节
	head.flag = ACK;
	srand((unsigned)time(NULL));
	head.seq_num = recv_head->ack_num;//产生随机序列号
	head.ack_num = recv_head->seq_num + 1;
	head.ck_sum = 0;
	head.ck_sum = cksum((u_short*)&head, head.len / 2 + head.len % 2);
	cout << "第三次握手中Ack为" << (int)recv_head->ack_num << endl;
	cout << "第三次握手中Seq为" << (int)recv_head->seq_num << endl;

	memcpy(buf, &head, head.len);
	while (sendto(sock, buf, head.len, 0, (struct sockaddr*)&sockAddr, sizeof(sockAddr)) == SOCKET_ERROR) {
		cout << "send发送失败！重新发送..." << endl;
	}
	cout << "第三次握手已发送.....可以进行数据传输..." << endl;

	//数据传输




	closesocket(sock);
	WSACleanup();
	return 0;
}
